package com.ribbon.config;

import com.alibaba.cloud.nacos.NacosDiscoveryProperties;
import com.alibaba.cloud.nacos.NacosServiceManager;
import com.alibaba.cloud.nacos.ribbon.NacosServer;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.NamingService;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.alibaba.nacos.client.naming.core.Balancer;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.BaseLoadBalancer;
import com.netflix.loadbalancer.Server;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

public class ClusterWeightRule extends AbstractLoadBalancerRule {

    @Resource
    private NacosDiscoveryProperties ndps;

    @Resource
    private NacosServiceManager nsm;


    @Override
    public Server choose(Object o) {
        //得到当前这次请求正在访问的服务的服务名
        String name = ((BaseLoadBalancer)getLoadBalancer()).getName();
        //得到当前发请求的节点的注册信息
        String group = ndps.getGroup();
        String clusterName = ndps.getClusterName();
        //通过服务名得到该服务的所有健康的节点
        NamingService client = nsm.getNamingService(ndps.getNacosProperties());
        try {
            List<Instance> ins = client.selectInstances(name, group, true);
            //筛选出跟当前服务节点集群名相同的节点
            List<Instance> cluesterIns = ins.stream().filter(x -> x.getClusterName().equals(clusterName)).collect(Collectors.toList());
            if(cluesterIns == null || cluesterIns.size() <= 0) cluesterIns = ins;
            //权重算法选一个
            Instance instance = MyBalancer.getRandomWeight(cluesterIns);
            return new NacosServer(instance);
        } catch (NacosException e) {
            e.printStackTrace();
        }
        return null;
    }


    @Override
    public void initWithNiwsConfig(IClientConfig iClientConfig) {

    }

    static class MyBalancer extends Balancer {
        public static Instance getRandomWeight(List<Instance> hosts) {
            return Balancer.getHostByRandomWeight(hosts);
        }
    }

}
